﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace AirWar
{
    public partial class FormMain : Form
    {
        //地图类对象
        private Map _map;
        //我方飞机
        private Fighter _myFighter;
        //敌方飞机集合
        private List<Fighter> _listEnemyFighter = new List<Fighter> { };
        //游戏结束Bitmap对象
        Bitmap imgGameOver = new Bitmap("Image\\gameOver.png");
        //游戏状态
        private GameState _gameState = GameState.Close;
        //我方子弹List集合
        private List<Bullet> _listMyBullet = new List<Bullet> { };
        //敌方子弹List集合
        private List<Bullet> _listEnemyBullet = new List<Bullet> { };
        //项目exe文件的所在路径
        private string _exePath = "";
        //ini配置文件的路径和名称
        private string _iniPathFile = "";
        //玩家目前的最高得分
        private int _maxScore = 0;
        //导入动态链接库的键盘按键检测API函数
        [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
        public static extern short GetAsyncKeyState(int keyCode);
        //导入动态链接库
        [DllImport("kernel32")]
        public static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
        [DllImport("kernel32")]
        public static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
        //构造方法
        public FormMain()
        {
            InitializeComponent();
            //新建地图类对象，并装载荒漠地图
            _map = new Map("Image\\mapDesert.jpg");
            //生成一架我方飞机
            _myFighter = new Fighter(Side.Me, _map._Size);
            //设置exe
            string exePathFileName = Process.GetCurrentProcess().MainModule.FileName;
            _exePath = System.IO.Path.GetDirectoryName(exePathFileName) + "\\";
            _iniPathFile = _exePath + "Setting.ini";
            //读取最高分
            try
            {
                _maxScore = Convert.ToInt32(ReadStringFromIni("score", "maxScore"));
            }
            catch
            {
                _maxScore = 0;
            }
        }
        public void MyBulletHitEnemyFighter()
        {
            //遍历我方子弹
            for(int i = 0; i <= _listMyBullet.Count-1; i++)
            {
                //遍历敌方飞机
                for(int j = 0;j <= _listEnemyFighter.Count - 1; j++)
                {
                    //我方子弹所处的Rectangle对象
                    Rectangle myBulletRect = new Rectangle(_listMyBullet[i]._Position.X, _listMyBullet[i]._Position.Y,
                                                          _listMyBullet[i]._Size.Width, _listMyBullet[i]._Size.Height);
                    //敌方飞机所处的Rectangle对象
                    Rectangle enemyFighterRect = new Rectangle(_listEnemyFighter[j].Position.X, _listEnemyFighter[j].Position.Y,
                                                          _listEnemyFighter[j].Size.Width, _listEnemyFighter[j].Size.Height);
                    //如果我方子弹与敌方飞机有交叉，则击中敌方飞机
                    if (myBulletRect.IntersectsWith(enemyFighterRect))
                    {
                        //我方飞机的分值加1
                        _myFighter.Score += 1;
                        //敌方飞机的生命值变0
                        _listEnemyFighter[j].LifeValue = 0;
                        //我方子弹失效
                        _listMyBullet[i]._Enable = false;
                        //播放敌方飞机爆炸音效
                        axWindowsMediaPlayerFighterExplode.Ctlcontrols.play();
                        //子弹只打一架飞机,退出当前循环
                        break;
                    }
                }
            }
        }
        //(自定义方法)处理敌方子弹击中我方飞机
        public void EnemyBulletHitMyFighter()
        {
            //如果我方飞机生命值>0
            if(_myFighter.LifeValue > 0)
            {
                //遍历敌方子弹
                for(int i = 0; i <= _listEnemyBullet.Count - 1; i++)
                {
                    //敌方子弹的Rectangle对象
                    Rectangle enemyBulletRect = new Rectangle(_listEnemyBullet[i]._Position.X, _listEnemyBullet[i]._Position.Y,
                                                         _listEnemyBullet[i]._Size.Width, _listEnemyBullet[i]._Size.Height);
                    //我方飞机所处的Rectangle对象
                    Rectangle myFighterRect = new Rectangle(_myFighter.Position.X, _myFighter.Position.Y,
                                                          _myFighter.Size.Width, _myFighter.Size.Height);
                    //如果敌方子弹与我方飞机有交叉
                    if (enemyBulletRect.IntersectsWith(myFighterRect))
                    {
                        //我方飞机生命值-10
                        _myFighter.LifeValue -= 10;
                        //敌方子弹失效
                        _listEnemyBullet[i]._Enable = false;
                        //播放我方飞机被击中的音效
                        axWindowsMediaPlayerHitMyFighter.Ctlcontrols.play();
                    }
                }
            }
        }
        //(自定义方法)处理敌方飞机撞击我方飞机
        public void EnemyFighterHitMyFighter()
        {
            //如果我方飞机生命值>0
            if (_myFighter.LifeValue > 0)
            {
                //我方飞机所处的Rectangle对象
                Rectangle myFighterRect = new Rectangle(_myFighter.Position.X, _myFighter.Position.Y,
                                                         _myFighter.Size.Width, _myFighter.Size.Height);
                //遍历敌方飞机
                for(int i = 0; i <= _listEnemyFighter.Count - 1; i++)
                {
                    //敌方飞机所处的Rectangle
                    Rectangle enemyFighterRect = new Rectangle(_listEnemyFighter[i].Position.X, _listEnemyFighter[i].Position.Y,
                                                       _listEnemyFighter[i].Size.Width, _listEnemyFighter[i].Size.Height);
                    //如果我方飞机与敌方飞机有交叉
                    if (myFighterRect.IntersectsWith(enemyFighterRect))
                    {
                        //我方飞机生命值-15
                        _myFighter.LifeValue -= 15;
                        //我方飞机分值+1
                        _myFighter.Score += 1;
                        //敌方飞机生命值0
                        _listEnemyFighter[i].LifeValue = 0;
                        //播放敌方飞机爆炸音效
                        axWindowsMediaPlayerFighterExplode.Ctlcontrols.play();
                        //播放我方飞机被击中的音效
                        axWindowsMediaPlayerHitMyFighter.Ctlcontrols.play();
                    }
                }
            }
        }
        //(自定义方法)从_iniPathFile配置文件读取配置信息
        public string ReadStringFromIni(string Section, string Key)
        {
            StringBuilder temp = new StringBuilder(255);
            int i = GetPrivateProfileString(Section, Key, "", temp, 255, _iniPathFile);
            return temp.ToString();
        }
        //(自定义方法)向_iniPathFile配置文件写入配置信息
        public void WriteStringToIni(string Section, string Key, string Value)
        {
            WritePrivateProfileString(Section, Key, Value, _iniPathFile);
        }
        private void FormMain_Load(object sender, EventArgs e)
        {
            //设置主窗口客户区的尺寸等于地图的尺寸
            this.ClientSize = _map._Size;
            //让窗口顶部对齐屏幕顶部
            this.Top = 0;
            //设置axWindowsMediaPlayerBgMusic不可见
            axWindowsMediaPlayerBgMusic.Visible = false;
            //axWindowsMediaPlayerBgMusic设置音乐文件并自动播放
            axWindowsMediaPlayerBgMusic.URL = "Sound\\backgroundMusic.mp3";
            axWindowsMediaPlayerBgMusic.Ctlcontrols.play();
            //设置axWindowsMediaPlayerFighterExplode不可见
            axWindowsMediaPlayerFighterExplode.Visible = false;
            //axWindowsMediaPlayerFighterExplode设置音乐文件并自动播放
            axWindowsMediaPlayerFighterExplode.URL = "Sound\\fighterExplode.wav";
            axWindowsMediaPlayerFighterExplode.Ctlcontrols.stop();
            //设置axWindowsMediaPlayerHitMyFighter不可见
            axWindowsMediaPlayerHitMyFighter.Visible = false;
            //axWindowsMediaPlayerHitMyFighter设置音乐文件并自动播放
            axWindowsMediaPlayerHitMyFighter.URL = "Sound\\hitMyFighter.wav";
            axWindowsMediaPlayerHitMyFighter.Ctlcontrols.stop();
        }
        //pictureBoxMap组件的Paint事件响应方法
        private void pictureBoxMap_Paint(object sender, PaintEventArgs e)
        {
            //绘制地图
            _map.DrawMe(e.Graphics );
            //处理我方子弹击中敌方飞机
            MyBulletHitEnemyFighter();
            //处理敌方子弹击中我方飞机
            EnemyBulletHitMyFighter();
            //处理敌方飞机碰撞我方飞机
            EnemyFighterHitMyFighter();
            //移除失效的我方子弹
            for (int i = _listMyBullet.Count - 1; i >= 0; i--)
                if (_listMyBullet[i]._Enable == false || _listMyBullet[i]._Position.Y <= -10)
                    _listMyBullet.RemoveAt(i);
            //移除生命值为0的敌方飞机
            for (int i = _listEnemyFighter.Count - 1; i >= 0; i--)
                if (_listEnemyFighter[i].LifeValue == 0 || _listEnemyFighter[i].Position.Y >= _map._Size.Height)
                {
                    //如果敌方飞机的生命值为0，绘制爆炸
                    if (_listEnemyFighter[i].LifeValue == 0)
                        _listEnemyFighter[i].Explode(e.Graphics);
                    //从敌方飞机集合移除
                    _listEnemyFighter.RemoveAt(i);
                }
            //移除失效的敌方子弹
            for (int i = _listEnemyBullet.Count - 1; i >= 0; i--)
                if (_listEnemyBullet[i]._Enable == false || _listEnemyBullet[i]._Position.Y >= _map._Size.Height)
                    _listEnemyBullet.RemoveAt(i);
            //如果我方飞机生命大于0，则绘制出我方飞机
            if (_myFighter.LifeValue > 0)
                _myFighter.DrawMe(e.Graphics);
            //逐一绘制出敌方飞机
            foreach (Fighter enemyFighter in _listEnemyFighter)
                enemyFighter.DrawMe(e.Graphics);
            //逐一绘制我方子弹
            foreach (Bullet myBullet in _listMyBullet)
                myBullet.DrawMe(e.Graphics);
            //逐一绘制敌方子弹
            foreach (Bullet enemyBullet in _listEnemyBullet)
                enemyBullet.DrawMe(e.Graphics);
            //绘制我方飞机的生命值和分数
            e.Graphics.DrawRectangle(new Pen(Color.Black), new Rectangle(10, 20, 101, 10));
            e.Graphics.FillRectangle(Brushes.Red, 11, 21, _myFighter.LifeValue, 9);
            e.Graphics.DrawString("得分:" + _myFighter.Score, new Font("宋体", 9, FontStyle.Bold),
                                  Brushes.Yellow, new Point(10, 40));
            //如果我方飞机的生命值小于等于0，则结束游戏
            if(_myFighter.LifeValue<=0)
            {
                //在地图中央绘制游戏结束的提示画面
                e.Graphics.DrawImage(imgGameOver, (_map._Size.Width - imgGameOver.Width) / 2, (_map._Size.Height - imgGameOver.Height) / 2);
                //结束游戏
                _gameState = GameState.Close;
                //最高分
                if(_myFighter.Score>=_maxScore)
                {
                    _maxScore = _myFighter.Score;
                    e.Graphics.DrawString("您的得分为" + _myFighter.Score.ToString() + "，恭喜您荣登得分榜榜首！",
                                          new Font("微软雅黑", 16, FontStyle.Bold), Brushes.Yellow,
                                          new Point(28, _map._Size.Height / 2 + 60));
                }
            }
        }
        private void timerPaintPictureBox_Tick(object sender, EventArgs e)
        {
            //让图片向下滚动两个像素点
            _map.Scroll(2);
            //实现我方飞机的方向控制和子弹发射
            if(_gameState == GameState.Open)
            {
                //检测我方飞机的方向按键
                bool downPressed = (((ushort)GetAsyncKeyState((int)Keys.Down)) & 0xffff) != 0;
                if (downPressed == true)
                    _myFighter.Move(Direction.Down, _map._Size);
                bool upPressed = (((ushort)GetAsyncKeyState((int)Keys.Up)) & 0xffff) != 0;
                if (upPressed == true)
                    _myFighter.Move(Direction.Up, _map._Size);
                bool leftPressed = (((ushort)GetAsyncKeyState((int)Keys.Left)) & 0xffff) != 0;
                if (leftPressed == true)
                    _myFighter.Move(Direction.Left, _map._Size);
                bool rightPressed = (((ushort)GetAsyncKeyState((int)Keys.Right)) & 0xffff) != 0;
                if (rightPressed == true)
                    _myFighter.Move(Direction.Right, _map._Size);
                //检测我方飞机的开火按键
                bool spacePressed = (((ushort)GetAsyncKeyState((int)Keys.Space)) & 0xffff) != 0;
                if(spacePressed == true)
                {
                    //产生一颗子弹并添加到我方子弹集合中
                    Bullet myBullet = _myFighter.Fire();
                    _listMyBullet.Add(myBullet);
                }
            }
            //按一定概率随机控制敌方飞机的移动方向
            Random enemyRand = new Random(DateTime.Now.Second);
            foreach(Fighter enemyFighter in _listEnemyFighter)
            {
                //产生一个随机数
                int direction = enemyRand.Next(1, 6);
                //让敌方飞机移动一个步长
                if (direction == 1)
                    enemyFighter.Move(Direction.Left, _map._Size);
                else if (direction == 2)
                    enemyFighter.Move(Direction.Right, _map._Size);
                else
                    enemyFighter.Move(Direction.Down, _map._Size);
            }
            //让我方子弹动起来
            foreach (Bullet myBullet in _listMyBullet)
                myBullet.Move();
            //让敌方子弹动起来
            foreach (Bullet enemyBullet in _listEnemyBullet)
                enemyBullet.Move();
            //强制刷新PictureboxMap组件
            pictureBoxMap.Invalidate();
        }

        private void ToolStripMenuItemMapDesert_Click(object sender, EventArgs e)
        {
            //新建地图类对象，并装载荒漠地图
            _map = new Map("Image\\mapDesert.jpg");
            //强制刷新PictureboxMap组件
            pictureBoxMap.Invalidate();
            ToolStripMenuItemMapDesert.Checked = true;
            ToolStripMenuItemMapForest.Checked = false;
            ToolStripMenuItemMapCastle.Checked = false;
            ToolStripMenuItemMapBase.Checked = false;
        }

        private void ToolStripMenuItemMapForest_Click(object sender, EventArgs e)
        {
            //新建地图类对象，并装载森林地图
            _map = new Map("Image\\mapForest.jpg");
            //强制刷新PictureboxMap组件
            pictureBoxMap.Invalidate();
            ToolStripMenuItemMapDesert.Checked = false;
            ToolStripMenuItemMapForest.Checked = true;
            ToolStripMenuItemMapCastle.Checked = false;
            ToolStripMenuItemMapBase.Checked = false;
        }

        private void ToolStripMenuItemMapCastle_Click(object sender, EventArgs e)
        {
            //新建地图类对象，并装载城堡地图
            _map = new Map("Image\\mapCastle.jpg");
            //强制刷新PictureboxMap组件
            pictureBoxMap.Invalidate();
            ToolStripMenuItemMapDesert.Checked = false;
            ToolStripMenuItemMapForest.Checked = false;
            ToolStripMenuItemMapCastle.Checked = true;
            ToolStripMenuItemMapBase.Checked = false;
        }

        private void ToolStripMenuItemMapBase_Click(object sender, EventArgs e)
        {
            //新建地图类对象，并装载基地地图
            _map = new Map("Image\\mapBase.jpg");
            //强制刷新PictureboxMap组件
            pictureBoxMap.Invalidate();
            ToolStripMenuItemMapDesert.Checked = false;
            ToolStripMenuItemMapForest.Checked = false;
            ToolStripMenuItemMapCastle.Checked = false;
            ToolStripMenuItemMapBase.Checked = true;
        }

        private void ToolStripMenuItemGameBegin_Click(object sender, EventArgs e)
        {
            //设置游戏状态为Open
            _gameState = GameState.Open;
            //重新生成一家我方飞机
            _myFighter = new Fighter(Side.Me, _map._Size);
            //清空
            _listEnemyFighter.Clear();
            _listEnemyBullet.Clear();
            _listMyBullet.Clear();
            //重新播放背景音乐
            axWindowsMediaPlayerBgMusic.Ctlcontrols.stop();
            axWindowsMediaPlayerBgMusic.Ctlcontrols.play();
        }

        private void ToolStripMenuItemGameEnd_Click(object sender, EventArgs e)
        {
            _myFighter.LifeValue = 0;
            _gameState = GameState.Close;
        }
        //键盘下压事件响应方法
        private void FormMain_KeyDown(object sender, KeyEventArgs e)
        {
            
        }

        private void timerGenerateEnemyFighter_Tick(object sender, EventArgs e)
        {
            //判断游戏是否处于Open状态
            if(_gameState == GameState.Open)
            {
                //定时产生一架敌方飞机
                Fighter enemyFighter = new Fighter(Side.Enemy, _map._Size);
                //把敌方飞机添加到敌机集合中
                _listEnemyFighter.Add(enemyFighter);
            }
        }

        private void timerEnemyFighterFire_Tick(object sender, EventArgs e)
        {
            if(_gameState == GameState.Open)
            {
                Random myRand = new Random(DateTime.Now.Second);
                foreach(Fighter enemyFighter in _listEnemyFighter)
                {
                    int fireFlag = myRand.Next(1, 7);
                    if(fireFlag <= 4)
                    {
                        Bullet enemyBullet = enemyFighter.Fire();
                        _listEnemyBullet.Add(enemyBullet);
                    }
                }
            }
        }
        private void FormMain_FormClosed(object sender, FormClosedEventArgs e)
        {
            WriteStringToIni("score", "maxScore", _maxScore.ToString());
        }
    }
}
